package org.payeco.risk.service.impl;

import java.util.List;

import org.payeco.risk.dao.PayecoRuleModularRepository;
import org.payeco.risk.entity.PayecoRuleModular;
import org.payeco.risk.service.PayecoRuleModularService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.google.common.base.Objects;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Ordering;

@Service
public class PayecoRuleModularServiceImpl implements
		PayecoRuleModularService<String> {

	private final Logger log = LoggerFactory.getLogger(this.getClass());

	@Autowired
	PayecoRuleModularRepository modularRepository;

	private List<PayecoRuleModular> findModulars() {
		List<PayecoRuleModular> modulars = Lists.newArrayList();
		modulars.addAll(modularRepository.findByState("State.Enabled"));
		// sort modulars;
		Ordering<PayecoRuleModular> sortByPriority = new Ordering<PayecoRuleModular>() {

			@Override
			public int compare(PayecoRuleModular left, PayecoRuleModular right) {
				System.out.println("r:" + right.getPriority() + "compare to l:"
						+ left.getPriority());
				return right.getPriority() - left.getPriority();
			}
		};
		return sortByPriority.immutableSortedCopy(modulars);
	}

	private boolean isNeedModular(PayecoRuleModular modular, String bank,
			String sysMerchantNo, String industry, String cardType,
			String userlevel, String checkMode) {
		
		if(!modular.getCheckmode().contains(checkMode)){
			return false;
		}
		boolean isMatched1 = Objects.equal("Generic", modular.getAccountType()) || modular.getAccountType().contains(cardType);
		if (((isMatched1 && modular.getAccountType().startsWith("exclude")) //包含但是豁免
				|| (!isMatched1 && !modular.getAccountType().startsWith("exclude")))) {//不包含但是不豁免
			return false;
		}
		boolean isMatched2 = Objects.equal("Generic", modular.getBanks()) || modular.getBanks().contains(bank);
		if (((isMatched2 && modular.getBanks().startsWith("exclude")) 
				|| (!isMatched2 && !modular.getBanks().startsWith("exclude")))) {
			return false;
		}
		boolean isMatched3 = Objects.equal("Generic", modular.getSysmerchantnoes()) || modular.getSysmerchantnoes().contains(sysMerchantNo);
		if (((isMatched3 && modular.getSysmerchantnoes().startsWith("exclude")) 
				|| (!isMatched3 && !modular.getSysmerchantnoes().startsWith("exclude")))) {
			return false;
		}
		boolean isMatched4 = Objects.equal("Generic", modular.getIndustrys()) || modular.getIndustrys().contains(industry);
		if (((isMatched4 && modular.getIndustrys().startsWith("exclude")) 
				|| (!isMatched4 && !modular.getIndustrys().startsWith("exclude")))) {
			return false;
		}
		boolean isMatched5 = Objects.equal("Generic", modular.getUserlevel()) || modular.getUserlevel().contains(userlevel);
		if (((isMatched5 && modular.getUserlevel().startsWith("exclude")) 
				|| (!isMatched5 && !modular.getUserlevel().startsWith("exclude")))) {
			return false;
		}
		return true;
	}

	public List<PayecoRuleModular> findModularWithParamTypes(
			String bank, String sysMerchantNo, String industry,
			String cardType, String userlevel, String checkMode) {
		List<PayecoRuleModular> chooseModulars = Lists.newArrayList();
		List<PayecoRuleModular> modulars = findModulars();
		for (PayecoRuleModular modular : modulars) {
			if (isNeedModular(modular, bank, sysMerchantNo, industry, cardType,
					userlevel, checkMode)) {
				chooseModulars.add(modular);
			}
		}
		return chooseModulars;
	}

	@Override
	public List findModularsByElements(String... elements) {
		
		
		if (elements.length == 6) {
			return findModularWithParamTypes(
					elements[0], elements[1], elements[2], elements[3],
					elements[4], elements[5]);
		} else {
			List<PayecoRuleModular> chooseModulars = Lists.newArrayList();
			List<PayecoRuleModular> modulars = findModulars();
			for (PayecoRuleModular modular : modulars) {
				if (isNeedModular(modular, elements)) {
					chooseModulars.add(modular);
				}
			}
			return chooseModulars;
		}
	}

	public boolean isNeedModular(PayecoRuleModular modular, String... elements) {
		int len = elements.length;// 参数
		int count = 0;
		count = Objects.equal("Generic", modular.getAccountType()) ?  count++ : count;
		count = Objects.equal("Generic", modular.getBanks()) ? count++ : count;
		count = Objects.equal("Generic", modular.getSysmerchantnoes()) ? count++ : count;
		count = Objects.equal("Generic", modular.getIndustrys()) ? count++ : count;
		count = Objects.equal("Generic", modular.getUserlevel()) ? count++ : count;
		for (String el : elements) {
			boolean isMatched1 = modular.getAccountType().contains(el);
			if (((isMatched1 && !modular.getAccountType().startsWith("exclude")) 
					|| (!isMatched1 && modular.getAccountType().startsWith("exclude")))) {
				count++;
			}
			boolean isMatched2 = modular.getBanks().contains(el);
			if (((isMatched2 && !modular.getBanks().startsWith("exclude")) 
					|| (!isMatched2 && modular.getBanks().startsWith("exclude")))) {
				count++;
			}
			boolean isMatched3 = modular.getSysmerchantnoes().contains(el);
			if (((isMatched3 && !modular.getSysmerchantnoes().startsWith("exclude")) 
					|| (!isMatched3 && modular.getSysmerchantnoes().startsWith("exclude")))) {
				count++;
			}
			boolean isMatched4 = modular.getIndustrys().contains(el);
			if (((isMatched4 && !modular.getIndustrys().startsWith("exclude")) 
					|| (!isMatched4 && modular.getIndustrys().startsWith("exclude")))) {
				count++;
			}
			boolean isMatched5 = modular.getUserlevel().contains(el);
			if (((isMatched5 && !modular.getUserlevel().startsWith("exclude")) 
					|| (!isMatched5 && modular.getUserlevel().startsWith("exclude")))) {
				count++;
			}
		}
		// TODO Auto-generated method stub
		return count == len;
	}

}
